package com.aqie.rabbit.service.Impl;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aqie.rabbit.bean.api.base.CodeMsg;
import com.aqie.rabbit.bean.api.base.ResponseModel;
import com.aqie.rabbit.redis.IRedisService;
import com.aqie.rabbit.service.ISmsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Random;

import static com.aqie.rabbit.redis.keyPrefix.SmsKey.SmsContentGapKey;
import static com.aqie.rabbit.redis.keyPrefix.SmsKey.SmsContentValidKey;

@Service
@Slf4j
public class SmsServiceImpl implements ISmsService, InitializingBean {
    @Value("${aliyun.sms.accessKey}")
    private String accessKey;

    @Value("${aliyun.sms.accessKeySecret}")
    private String secertKey;

    @Value("${aliyun.sms.template.code}")
    private String templateCode;


    private IAcsClient acsClient;



    private static final String[] NUMS = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
    private static final Random random = new Random();

    @Autowired
    IRedisService redisService;

    @Override
    public ResponseModel sendSms(String telephone) {
        // 先从redis中拿，拿不到说明未发送过短信
        String result = redisService.get(SmsContentGapKey,telephone,String.class);
        if (result != null){
            return ResponseModel.error(CodeMsg.PARAMETER_ERROR);
        }

        // 获取验证码
        String code = generateRandomSmsCode();
        String templateParam = String.format("{\"code\": \"%s\"}", code);

        // 组装请求对象
        SendSmsRequest request = new SendSmsRequest();

        // 使用post提交
        request.setMethod(MethodType.POST);
        request.setPhoneNumbers(telephone);
        request.setTemplateParam(templateParam);
        request.setTemplateCode(templateCode);
        request.setSignName("康忠礼");

        boolean success = false;
        try {
            SendSmsResponse response = acsClient.getAcsResponse(request);

            if ("OK".equals(response.getCode())) {
                success = true;
            } else {
                // log.info("sms response:{}", response);
            }
        } catch (ClientException e) {
            e.printStackTrace();
        }

        // 发送短信成功存储在redis
        if (success){
            redisService.set(SmsContentGapKey,telephone,code);
            redisService.set(SmsContentValidKey,telephone,code);
            return ResponseModel.success(code);
        }else{
            return ResponseModel.error(CodeMsg.SMS_SERVER_ERROR);
        }

    }

    @Override
    public String getSmsCode(String telephone) {
        return redisService.get(SmsContentValidKey,telephone, String.class);
    }

    @Override
    public void remove(String telephone) {
        redisService.delete(SmsContentValidKey,telephone);
    }

    // 初始化client
    @Override
    public void afterPropertiesSet() throws Exception {
        // 设置超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKey, secertKey);

        // 固定的
        String product = "Dysmsapi";
        String domain = "dysmsapi.aliyuncs.com";

        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
        this.acsClient = new DefaultAcsClient(profile);
    }

    /**
     * @return 6位验证码生成器
     */
    private static String generateRandomSmsCode() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            int index = random.nextInt(10);
            sb.append(NUMS[index]);
        }
        return sb.toString();
    }
}
